package com.ciaojian.core.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.MessageDigest;

/**
 * 加密
 * 
 * @author worm
 * 
 */
public class SecretHelper {
	
	private static final Logger logger = LoggerFactory.getLogger(SecretHelper.class);

	/**
	 * 
	 * @param info
	 * @return
	 * @throws Exception
	 */
	private static SecretKey _deskey;

	private static Cipher _c1;
	static {
		try {
			_deskey = KeyGenerator.getInstance("DES").generateKey();
			_c1 = Cipher.getInstance("DES");
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
	}

	public static String encodeByDES(String info) throws Exception {
		Cipher cipher = Cipher.getInstance("DES");
		cipher.init(Cipher.ENCRYPT_MODE, _deskey);
		byte[] cipherByte = cipher.doFinal(info.getBytes());
		return byteToStr(cipherByte, false);
	}

	/**
	 * 
	 * @param info
	 * @return
	 * @throws Exception
	 */
	public static String decodeByDES(String info) throws Exception {
		Cipher cipher = Cipher.getInstance("DES");
		cipher.init(Cipher.DECRYPT_MODE, _deskey);
		byte[] clearByte = cipher.doFinal(strToByte(info));
		return byteToStr(clearByte, true);
	}

	/**
	 * 
	 * @param array
	 * @return
	 */
	private static String byteToStr(byte[] array, boolean isEncoding) throws Exception {
		if (isEncoding) {
			return new String(array, "GB2312");
		}
		// 确保能被byte能被正确保留下来
		char[] temp = new char[array.length];
		//
		for (int i = 0, len = array.length; i < len; i++) {
			temp[i] = (char) array[i];
		}
		//
		return new String(temp);
	}

	/**
	 * 
	 * @param src
	 * @return
	 */
	private static byte[] strToByte(String src) {
		char[] array = src.toCharArray();
		byte[] rets = new byte[array.length];
		for (int i = 0, len = array.length; i < len; i++) {
			rets[i] = (byte) array[i];
		}
		return rets;
	}

	/**
	 * 1-base64编码<br>
	 * 2-倒序<br>
	 * 3-奇偶交换<br>
	 * 
	 * @param str
	 * @return
	 */
	public static String encode(String str) {
		String vender = Base64.byteArrayToBase64(str.getBytes());
		char[] temp = vender.toCharArray();
		char pos;
		for (int i = 0, len = temp.length; i < len; i++) {
			pos = temp[i];
			temp[i] = temp[len - 1 - i];
			temp[len - 1 - i] = pos;
		}
		for (int i = 0, len = temp.length; i < len; i += 2) {
			if (i != (len - 1)) {
				pos = temp[i];
				temp[i] = temp[i + 1];
				temp[i + 1] = pos;
			}
		}
		return String.valueOf(temp);
	}

	/**
	 * 1-奇偶对调<br>
	 * 2-逆序<br>
	 * 3-base64
	 * 
	 * @param str
	 * @return
	 */
	public static String decode(String str) {
		if (str == null || str.equals(""))
			return "";
		char[] temp = str.toCharArray();
		char pos;
		for (int i = 0, len = temp.length; i < len; i += 2) {
			if (i != (len - 1)) {
				pos = temp[i];
				temp[i] = temp[i + 1];
				temp[i + 1] = pos;
			}
		}
		for (int i = 0, len = temp.length; i < len; i++) {
			pos = temp[i];
			temp[i] = temp[len - 1 - i];
			temp[len - 1 - i] = pos;
		}
		try {
			byte[] vender = Base64.base64ToByteArray(String.valueOf(temp));
			return new String(vender);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return "";
	}

	/**
	 * 根据选择的加密方式进行编码
	 * 
	 * @param content
	 * @param algorithm
	 *            支持md5
	 * @return
	 */
	public static String encodeByStyle(String content, String algorithm) {

		byte[] unencodedPassword = content.getBytes();

		MessageDigest md = null;

		try {
			// first create an instance, given the provider
			md = MessageDigest.getInstance(algorithm);
		} catch (Exception e) {// 忽略
			return content;
		}

		md.reset();

		// call the update method one or more times
		// (useful when you don't know the size of your data, eg. stream)
		md.update(unencodedPassword);

		// now calculate the hash
		byte[] encodedPassword = md.digest();

		StringBuffer buf = new StringBuffer();

		for (int i = 0; i < encodedPassword.length; i++) {
			if ((encodedPassword[i] & 0xff) < 0x10) {
				buf.append("0");
			}

			buf.append(Long.toString(encodedPassword[i] & 0xff, 16));
		}
		return buf.toString();
	}

}
